///////////////////////////////////////////////////////////
// 
//  MyBox.cpp
// 
//  Authors:  Jeremy Bennett
//
///////////////////////////////////////////////////////////

// Local Includes
#include "stdafx.h"
#include "MyCylinder.h"
#include "MyContext.h"

// SDL Includes
#include <SDL_opengl.h>

// Bullet Includes
#include <BulletCollision/CollisionShapes/btCylinderShape.h>
#include <LinearMath/btDefaultMotionState.h>

// System Includes

MyCylinder::MyCylinder( const btVector3 &vSize, 
                        const btVector3 &vOrigin, 
                        const btScalar   fMass ) 
: MyShape() 
{
    _eType = my_cylinder;

    _pShp = new btCylinderShapeZ(vSize);
	_vCol = btVector4(1.0f,0.0f,1.0f,1.0f);
    
    btTransform colTran;
	colTran.setIdentity();
    colTran.setOrigin(vOrigin);

    btVector3 locInertia(0,0,0);
    if ( fMass != 0 ) {
         _pShp->calculateLocalInertia(fMass,locInertia);
    }

    btDefaultMotionState* pMotState = new btDefaultMotionState(colTran);
    btRigidBody::btRigidBodyConstructionInfo rbInfo(fMass,pMotState,_pShp,locInertia);
	rbInfo.m_friction = 4.0f;
	rbInfo.m_angularDamping = 1.0f;
    setupRigidBody(rbInfo);

    if ( fMass != 0 ) {
        setLinearFactor(btVector3(1,1,1));
	    setAngularFactor(btVector3(0,0,1));
	    setCcdMotionThreshold(0.1);
	    setCcdSweptSphereRadius(0.2f);
    }
}

MyCylinder::~MyCylinder() 
{
}

bool 
MyCylinder::render( MyContext *ctx )
{
    // TOIXC: NYI:

    //return true;
    btScalar	m[16];

    btDefaultMotionState *pMotState = (btDefaultMotionState*)getMotionState();
    pMotState->m_graphicsWorldTrans.getOpenGLMatrix(m);

    glEnable(GL_COLOR_MATERIAL);
    glColor4f( _vCol[0], _vCol[1], _vCol[2], _vCol[3] );

#if 1
    glPushMatrix(); 
	glMultMatrixf(m);

	const btBoxShape* boxShape = static_cast<const btBoxShape*>(_pShp);
	btVector3 halfExtent = boxShape->getHalfExtentsWithMargin();
	
    float radius     = halfExtent[0];
    float halfHeight = halfExtent[2];
    int   upAxis     = 2;

	glPushMatrix();
	switch (upAxis)
	{
	case 0:
		glRotatef(-90.0, 0.0, 1.0, 0.0);
		glTranslatef(0.0, 0.0, -halfHeight);
		break;
	case 1:
		glRotatef(-90.0, 1.0, 0.0, 0.0);
		glTranslatef(0.0, 0.0, -halfHeight);
		break;
	case 2:

		glTranslatef(0.0, 0.0, -halfHeight);
		break;
	default:
		{
			btAssert(0);
		}

	}

	GLUquadricObj *quadObj = gluNewQuadric();

	//The gluCylinder subroutine draws a cylinder that is oriented along the z axis. 
	//The base of the cylinder is placed at z = 0; the top of the cylinder is placed at z=height. 
	//Like a sphere, the cylinder is subdivided around the z axis into slices and along the z axis into stacks.

	gluQuadricDrawStyle(quadObj, (GLenum)GLU_FILL);
	gluQuadricNormals(quadObj, (GLenum)GLU_SMOOTH);

	gluDisk(quadObj,0,radius,15, 10);

	gluCylinder(quadObj, radius, radius, 2.f*halfHeight, 15, 10);
	glTranslatef(0.0f, 0.0f, 2.0f*halfHeight);
	glRotatef(-180.0f, 0.0f, 1.0f, 0.0f);
	gluDisk(quadObj,0,radius,15, 10);

	glPopMatrix();
	gluDeleteQuadric(quadObj);

        glPopMatrix();
#endif

    return true;
}